package com.legstar.talend;

import java.util.Map;

import com.legstar.coxb.CobolBindingException;
import com.legstar.coxb.convert.simple.CobolSimpleConverters;
import com.legstar.coxb.host.HostContext;
import com.legstar.coxb.host.HostException;
import com.legstar.coxb.impl.visitor.FlatCobolUnmarshalVisitor;
import com.legstar.coxb.transform.AbstractTransformer;
import com.legstar.coxb.transform.HostTransformStatus;
import com.legstar.coxb.transform.IHostTransformers;
import com.legstar.coxb.util.BindingUtil;

/**
 * Mediator between LegStar and Talend APIs.
 * 
 */
public final class CobolToTalend {

    /**
     * Utility class.
     */
    private CobolToTalend() {

    }

    /*
     * ------------------------------------------------------------------------
     * Runtime Transformer execution.
     * ------------------------------------------------------------------------
     */

    /**
     * Create an instance of COBOL Transformers for a given JAXB root class
     * name. Assumes binding classes were generated for this JAXB class.
     * <p/>
     * Assumes the JAXB class is available from the classpath.
     * 
     * @param jaxbQualifiedClassName the JAXB class name
     * @return a new instance of Transformers
     */
    public static IHostTransformers newTransformers(
            final String jaxbQualifiedClassName) {
        try {
            return BindingUtil.newTransformers(jaxbQualifiedClassName);
        } catch (CobolBindingException e) {
            throw new RuntimeException(
                    "Failed to create LegStar transformers from "
                            + jaxbQualifiedClassName, e);
        }
    }

    /**
     * Creates a map of JAXB field names associated with values out from a host
     * data buffer.
     * <p/>
     * This results in a flattening of the data items which is what ETL tools
     * expect.
     * 
     * @param tf a host transformer
     * @param hostRecord the host data
     * @param hostCharset the host character set
     * @param status additional info on the COBOL to Java transformation process
     * @return a map of JAXB names associated with values
     */
    public static Map<String, Object> toValues(final IHostTransformers tf,
            final byte[] hostRecord, final String hostCharset,
            final HostTransformStatus status) {

        try {

            FlatCobolUnmarshalVisitor cev = new FlatCobolUnmarshalVisitor(
                    hostRecord, 0, new CobolSimpleConverters());
            ((AbstractTransformer) tf.getHostToJava()).getCachedBinding()
                    .accept(cev);
            status.setHostBytesProcessed(cev.getOffset());
            return cev.getKeyValues();

        } catch (CobolBindingException e) {
            throw new RuntimeException(e);
        } catch (HostException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * The default mainframe character set.
     * 
     * @return the default mainframe character set
     */
    public static String getDefaultHostCharset() {
        return HostContext.getDefaultHostCharsetName();
    }

}
